package com.scau.phr.business.hosipital.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.scau.phr.business.auth.domain.Session;
import com.scau.phr.business.auth.service.SessionService;
import com.scau.phr.business.auth.service.SimpleSessionServiceImpl;
import com.scau.phr.business.hosipital.domain.AppointmentApplyDto;
import com.scau.phr.business.hosipital.domain.AppointmentInfoDTO;
import com.scau.phr.business.message.Instant;
import com.scau.phr.business.message.service.MessageService;
import com.scau.phr.common.exceptions.ErrorCode;
import com.scau.phr.common.exceptions.ServiceException;
import com.scau.phr.domain.entity.Appointment;
import com.scau.phr.domain.mapper.AppointmentMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * 医院预约服务
 * @author yuzhiyi
 * @date 2018/8/7 16:10
 */
@Service
public class AppointmentService {


	private Logger logger = LoggerFactory.getLogger(AppointmentService.class);

	@Autowired @Qualifier(SimpleSessionServiceImpl.NAME)
	private SessionService sessionService;

	@Autowired
	private AppointmentMapper appointmentMapper;

	@Autowired
	private MessageService messageService;

	private ThreadLocal<ObjectMapper>  mapperThreadLocal = ThreadLocal.withInitial(ObjectMapper::new);



	/**
	 * 进行挂号
	 * @param apply
	 * @return
	 */
	public Object doAppointment(AppointmentApplyDto apply){
		Session session = sessionService.getCurrentSession();
		if (session == null){
			logger.debug("获取Session失败导致预约失败");
			throw new ServiceException(ErrorCode.SERVER_ERROR);
		}
		logger.debug("{} 用户正在进行预约",session.getUsername());
		Appointment appointment = apply.wrap(session.getUsername());
		//如果重复预约，返回相应的ErrorCode
		if (existAppointment(appointment.getUserId(),appointment.getHospitalId(),appointment.getStartTime())){
			throw new ServiceException(ErrorCode.APPOINT_DUPLICATE);
		}
		appointmentMapper.insert(appointment);
		//发送就诊提醒
		sendAppointmentMessage(appointment);
		return appointment;
	}

	/**
	 *	查询用户的挂号记录
	 */
	public Object getAppointmentHistory(String token){
		Session session = sessionService.getCurrentSession();
		if (session == null){
			logger.debug("获取Session：{}失败导致获取预约记录失败",token);
			throw new ServiceException(ErrorCode.SERVER_ERROR);
		}
		return appointmentMapper.getAppointHistory(session.getUsername());
	}


	/**
	 * 一天不能挂多次同一家医院的号
	 */
	private boolean existAppointment(String phone, Long hospitalId, LocalDate localDate){
		return appointmentMapper.queryExistedAppointment(phone, hospitalId, localDate) > 0 ;
	}

	/**
	 * 获取预约的详细信息
	 */
	public AppointmentInfoDTO getAppointmentInfo(Long id){
		return appointmentMapper.getAppointmentInfoByAppointmentId(id);
	}

	/**
	 * 发送预约提醒消息
	 */
	private void sendAppointmentMessage(Appointment appointment){
		Long id = appointment.getAppointmentId();
		AppointmentInfoDTO info = getAppointmentInfo(id);
		try {
			String sender = info.getHospitalName();
			String receiver = appointment.getUserId();
			String content = mapperThreadLocal.get().writeValueAsString(info);
			messageService.addMessage(sender,receiver,content, Instant.APPOINTMENT_TIP, LocalDateTime.of(info.getStartTime(), LocalTime.MIN));
		} catch (JsonProcessingException e) {
			logger.warn("Json解析错误:{}",e.getMessage());
		}
	}
}
